/*****************************************************************************
 * vlc_sound_control.c : GTK+ plugin for vlc
 *****************************************************************************/

#include "components/soundcontrol.h"

#include <vlc/vlc.h>
#include <vlc_interface.h>
#include <vlc_aout.h>

#include "vlc_connect.h"

#include "resources/stock_icons.h"
#include "gtk_extra/gtk_extra.h"

#define VLC_DEFAULT_SOUND_VALUE 50
#define VOLUME_MAX 200

/* Widget */

static void     vlc_sound_control_class_init (VlcSoundControlClass *klass);
static void     vlc_sound_control_init       (VlcSoundControl *sound);

G_DEFINE_TYPE (VlcSoundControl, vlc_sound_control, GTK_TYPE_HBOX);

/* Callbacks */

static void cb_toggled_button (GtkToggleButton *togglebutton, gpointer user_data);
static gboolean cb_change_value_hscale (GtkRange *range, GtkScrollType scroll, gdouble value, gpointer user_data);

/* Privates functions */

static void vlc_sound_control_set_button_state (VlcSoundControl *sound);
static void update_volume (gdouble value);

static void
vlc_sound_control_class_init (VlcSoundControlClass *klass)
{}

static void
vlc_sound_control_init (VlcSoundControl *sound)
{

  sound->value = 0.0;
  sound->muted_value = 0.0;

  sound->button = gtk_toggle_button_new ();
  gtk_button_set_relief (GTK_BUTTON (sound->button), GTK_RELIEF_NONE);
  g_signal_connect (G_OBJECT (sound->button), "toggled", G_CALLBACK (cb_toggled_button), sound);
   
  sound->hscale = gtk_hscale_new_with_range (0.0, 100.0, 10.0);
  gtk_scale_set_draw_value (GTK_SCALE (sound->hscale), FALSE);
  gtk_widget_set_size_request (GTK_WIDGET (sound->hscale), 90, -1);
  g_signal_connect (G_OBJECT (sound->hscale), "change-value", G_CALLBACK (cb_change_value_hscale), sound);
  
  gtk_range_set_value (GTK_RANGE (sound->hscale), VLC_DEFAULT_SOUND_VALUE);
  vlc_sound_control_set_button_state (sound);
    
}

GtkWidget*
vlc_sound_control_new (void)
{

  GtkWidget *hbox;  

  hbox = g_object_new (VLC_TYPE_SOUND_CONTROL, NULL);

  gtk_box_set_homogeneous (GTK_BOX (hbox), FALSE);
  gtk_box_set_spacing (GTK_BOX (hbox), 2);

  gtk_box_pack_start (GTK_BOX (hbox), VLC_SOUND_CONTROL (hbox)->button, FALSE, FALSE, 0);
  gtk_box_pack_start (GTK_BOX (hbox), VLC_SOUND_CONTROL (hbox)->hscale, FALSE, FALSE, 0);

  update_volume (VLC_DEFAULT_SOUND_VALUE);

  return hbox;
}

static void
vlc_sound_control_set_button_state (VlcSoundControl *sound)
{

  GtkWidget *image;
  const guint8 *stock_id;
  gboolean change_state = FALSE;
  gdouble value;

  value = gtk_range_get_value (GTK_RANGE (sound->hscale));

  if (value <= 0)
   {
     stock_id = VLC_STOCK_AUDIO_MUTED;
     if (sound->value > 0)
      {
       change_state = TRUE;
      }
   }
  else if (value > 0 && value <= 33)
   {
    stock_id = VLC_STOCK_AUDIO_LOW;
    if (sound->value > 33 || sound->value == 0)
     {
      change_state = TRUE;
     }
   }
  else if (value > 33 && value <= 66)
   {
    stock_id = VLC_STOCK_AUDIO_MEDIUM;
    if (sound->value < 33 || sound->value > 66)
     {
      change_state = TRUE;
     }
   }
  else
   {
    stock_id = VLC_STOCK_AUDIO_HIGH;
    if (sound->value < 66)
     {
      change_state = TRUE;
     }
   }

  if (change_state)
   {
    image = gtk_image_new_from_vlc_stock (stock_id, VLC_ICON_SIZE_MENU);
    gtk_button_set_image (GTK_BUTTON (sound->button), image);
   }

  sound->value = value;

}

static void
update_volume (gdouble value)
{

  int vol;
  
  vol = value * (AOUT_VOLUME_MAX / 2) / VOLUME_MAX;
  vol = (vol < 0) ? 0 : vol;
  
  aout_VolumeSet (VLC_INTF_THREAD, vol);

}

static void
cb_toggled_button (GtkToggleButton *togglebutton, gpointer user_data)
{

  VlcSoundControl *sound;

  sound = VLC_SOUND_CONTROL (user_data);
  gdouble value;

  if (gtk_toggle_button_get_active (togglebutton))
   {
    sound->muted_value = sound->value;
    value = 0;
   }
  else
   {
    value = sound->muted_value;
   }
   
  gtk_range_set_value (GTK_RANGE (sound->hscale), value);
  vlc_sound_control_set_button_state (sound);
  update_volume (value);
  sound->value = value;

}

static gboolean
cb_change_value_hscale (GtkRange *range, GtkScrollType scroll, gdouble value, gpointer user_data)
{

  if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (VLC_SOUND_CONTROL (user_data)->button)) && value > 0)
   {
    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (VLC_SOUND_CONTROL (user_data)->button), FALSE);
   }
  
  gtk_range_set_value (range, value);
  
  vlc_sound_control_set_button_state (VLC_SOUND_CONTROL (user_data));
  
  update_volume (value);

  return TRUE;
  
}

